/***************************************************************************
 *   Copyright (C) 2009 by Marian Skvarek   *
 *   skvarek.marian@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A TrackICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "CTabExporter.h"
#include "CNoteGroupTablature.h"
#include "CScore.h"
#include "CPartGuitar.h"
#include "CPositionList.h"
#include "CSymbol.h"
#include "CNoteGroup.h"

#include <QLinkedList>
#include <QTextStream>

using namespace easyscore::core;

namespace easyscore
{
    namespace components
    {
        //Constructors, Destructors & Initialization
        CTabExporter::CTabExporter()
        {

        }


        CTabExporter::~CTabExporter()
        {

        }

        //Public methods
        bool CTabExporter::exportTablature(easyscore::core::CScore *score,QFile &file)
        {
            if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
                return false;

            QTextStream out(&file);

            out << "\t\tSong: " + score->getSongname() + '\n';
            out << "\t\tAuthor : " + score->getAuthorName() + '\n';
            out << "\t\tGenerated by Easyscore ( http://code.google.com/p/easyscore ) \n";
            out << "\n\n\n";

            foreach(CPart *part, score->getParts())
            {
                if(part->isGuitar())
                {
                    CPartGuitar *guitarPart = (CPartGuitar *)part;
                    if( !generateTablature( guitarPart ) )
                    {
                        return false;
                    }
                    else
                    {
                        for( int i = 0; i < STRING_COUNT; ++i )
                        {
                            foreach(CBar * bar, guitarPart->getTrack().getBars())
                            {
                                foreach(CSymbol *symbol, bar->getSymbols())
                                {
                                    if(symbol->isNoteGroup())
                                    {
                                        CNoteGroup *noteGroup = (CNoteGroup *)symbol;

                                        FRETBOARD_POSITION pos = noteGroup->getTab().get(i);
                                        if(pos == POSITION_NONE)
                                            out << "----";
                                        else
                                        {
                                            out << pos;

                                            //due to indentation
                                            if(pos < 10)
                                                out << '-';

                                            out << "--";
                                        }
                                    }
                                }

                                out << '|';
                            }

                            out << "\n";
                        }
                    }

                    out << "\n\n\n";
                }
            }

            file.close();

            return true;
        }

        //Protected methods
        bool CTabExporter::generateTablature(CPartGuitar *part)
        {
            QLinkedList<CSymbol*> symbols = part->getTrack().getSymbols();

            QLinkedList<CNoteGroup*> currNotes;
            CPositionList currentPositionList;
            currentPositionList.ones();
            foreach(CSymbol *symbol, symbols)
            {
                if(symbol->isNoteGroup())
                {
                    CNoteGroup *noteGroup = (CNoteGroup *)symbol;
                    //for each note group we get its position list
                    CPositionList currentNoteGroupPositionList = noteGroup->getPositionList();

                    //"AND" this position list with the currentPositionList
                    CPositionList newPositionList = currentPositionList;
                    newPositionList.andIt(currentNoteGroupPositionList);


                    if(newPositionList.isEmpty())
                    {
                        //if there is no position at which the previous note groups as well as a current note group
                        //could be played, then for previous notes set position in which they all can be played
                        setTablature(currNotes,currentPositionList);
                        currNotes.clear();
                        currentPositionList = currentNoteGroupPositionList;
                    }
                    else
                    {
                        //if there are still some positions at which the previous note group and a current note group can be
                        //played, then just update currentPositionList
                        currentPositionList = newPositionList;
                    }
                    currNotes.append(noteGroup);
                }
            }

            if(!currNotes.isEmpty())
            {
                setTablature(currNotes,currentPositionList);
            }

            return true;
        }

        //Protected methods
        void CTabExporter::setTablature(QLinkedList<CNoteGroup *> noteGroups,CPositionList list)
        {
            foreach(CNoteGroup *gr, noteGroups)
            {
                gr->setTablature(list.getFirstNonZero());
            }
        }

    }
}
